package edu.uci.ics.multicast.host;

/**
 * reference: http://darksleep.com/player/SocketExample/
 */

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.LinkedList;
import java.util.List;

public class Source {

	//private static final String SERVER_HOST_NAME = "localhost";
	static final int STREAMING_PORT = 52222;
	
	private String serverHostname = null;
	private int serverPort = 0;
	
	private List<Socket> listSocketChildren = new LinkedList<Socket>();
	
	public Source(String serverHostname, int serverPort){
		this.serverHostname =  serverHostname;
		this.serverPort = serverPort;
	}

	/**
	 * 	Figure out which father to connect to (request to rendezvous)
	 * 
	 * @throws SocketException
	 * @throws IOException
	 */
	private void registerRendezvous() throws SocketException, IOException {
		Socket sock = new Socket(serverHostname, serverPort);
		System.err.println("Connection openned with "+serverHostname+" port "+serverPort);
		sock.close();
	}

	private void generateStreaming() throws IOException, InterruptedException {
		for (int i=0; true; i++) {
			String data = "seqno_" + i;
			for (Socket sock : listSocketChildren) {
				ObjectOutputStream sockOutput = new ObjectOutputStream(sock.getOutputStream());
				sockOutput.writeObject(data);
				sockOutput.flush();
			}
			// Send packets every 5 seconds
			Thread.sleep(5000);
		}
	}

	private void addingNewChild() throws IOException {
		Runnable childTask = new Runnable(){
			public void run() {
				ServerSocket serverSock;
				try {
					serverSock = new ServerSocket(STREAMING_PORT);
					while (true) {
						Socket sock = serverSock.accept();
						listSocketChildren.add(sock);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
		new Thread(childTask).start();
	}
	
	public static void main(String argv[]) {
		Source source = new Source(argv[0], Rendezvous.ADMISSION_PORT);
		try {
			// peer request a father
			source.registerRendezvous();
			
			// wait for a request and add new child
			source.addingNewChild();
			
			// peer start to receive streaming
			source.generateStreaming();
		} catch (SocketException e) {
			e.printStackTrace(System.err);
		} catch (IOException e) {
			e.printStackTrace(System.err);
		} catch (InterruptedException e) {
			e.printStackTrace(System.err);
		}
	}

}
